package com.quanshi.cloudmeeting.ci.assistant;


import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.LineNumberReader;  
import java.util.ArrayList;  
import java.util.Iterator;
import java.util.List;  
import java.util.Properties;  
  
import java.util.Vector;

import com.jcraft.jsch.Channel;  
import com.jcraft.jsch.ChannelSftp; 
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;  
import com.jcraft.jsch.Session;  
import com.jcraft.jsch.SftpException;  
  
public class SFTPUtil {  
      
    private String host;  
    private String username;  
    private String password;  
    private int port = 22;  
    private ChannelSftp sftp = null;  
    private String localPath;  
    private String remotePath;  
    private String fileListPath = "/var/test/java/test.txt";  
    private final String seperator = "/";  
      
    
    public  SFTPUtil(String host,String username,String password,String localPath,String remotePath){
    	this.host=host;
    	this.username=username;
    	this.password=password;
    	this.localPath=localPath;
    	this.remotePath=remotePath;
    	
    }
   
    /** 
     * connect server via sftp 
     */  
    public void connect() {  
        try {  
            if(sftp != null){  
                System.out.println("sftp is not null");  
            }  
            JSch jsch = new JSch();  
            jsch.getSession(username, host, port);  
            Session sshSession = jsch.getSession(username, host, port);  
            System.out.println("Session created.");  
            sshSession.setPassword(password);  
            Properties sshConfig = new Properties();  
            sshConfig.put("StrictHostKeyChecking", "no");  
            sshSession.setConfig(sshConfig);  
            sshSession.connect();  
            System.out.println("Session connected.");  
            System.out.println("Opening Channel.");  
            Channel channel = sshSession.openChannel("sftp");  
            channel.connect();  
            sftp = (ChannelSftp) channel;  
            System.out.println("Connected to " + host + ".");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
    /** 
     * Disconnect with server 
     */  
    public void disconnect() {  
        if(this.sftp != null){  
            if(this.sftp.isConnected()){  
                this.sftp.disconnect();  
                System.out.println("Complete,sftp is closed");  
            }else if(this.sftp.isClosed()){  
                System.out.println("sftp is closed already");  
            }  
        }  
  
    }  
  
	public void downloadByDirectory(String directory, String saveDirectory)
			throws Exception {
		String downloadFile = "";
		List<String> downloadFileList = this.listFiles(directory);
		Iterator<String> it = downloadFileList.iterator();

		while (it.hasNext()) {
			downloadFile = it.next().toString();
		
			if (downloadFile.toString().indexOf(".") < 0) {
				continue;
			}
			this.download(directory, downloadFile, saveDirectory);
		}
	}
      
	
	public void download(String directory, String downloadFile, String saveDirectory) throws Exception { 
		
		
		String saveFile = saveDirectory + "//" + removeVersion(downloadFile); 

		this.sftp.cd(directory); 
		File file = new File(saveFile); 
		System.out.println("downloading file:"+downloadFile);
		
		
		this.sftp.get(downloadFile, new FileOutputStream(file)); 
	} 

	private String removeVersion(String downloadFile){
		if(downloadFile.endsWith(".apk") && downloadFile.length()<=32){
			System.out.println("rename file ["+downloadFile+"] to [TangClient.apk]");
			return "TangClient.apk";
		}else if(downloadFile.endsWith(".ipa") && downloadFile.length()<=32){
			System.out.println("rename file ["+downloadFile+"] to [TangClient.ipa]");
			return "TangClient.ipa";
		}
		return downloadFile;
	}
      
    private void download(String directory, String downloadFile,String saveFile, ChannelSftp sftp) {  
        try {  
            sftp.cd(directory);  
            File file = new File(saveFile);  
            sftp.get(downloadFile, new FileOutputStream(file));  
            
            List<String> files = listFiles(directory);
            
            
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
     
    
    private List<String> listFiles(String directory) throws Exception { 

    	Vector<?> fileList; 
    	List<String> fileNameList = new ArrayList<String>(); 
    	fileList = this.sftp.ls(directory); 
    	Iterator<?> it = fileList.iterator(); 
    	while(it.hasNext()) 
    	{ 
    	            String fileName = ((LsEntry)it.next()).getFilename(); 
    	            if(".".equals(fileName) || "..".equals(fileName)){ 
    	            continue; 
    	            } 
    	            fileNameList.add(fileName); 

    	} 

    	return fileNameList; 
    	} 
 
    /** 
     * upload all the files to the server 
     */  
    public void upload() {  
        List<String> fileList = this.getFileEntryList(fileListPath);  
        try {  
            if(fileList != null){  
                for (String filepath : fileList) {  
                    String localFile = this.localPath + this.seperator+ filepath;  
                    File file = new File(localFile);  
                      
                    if(file.isFile()){  
                        System.out.println("localFile : " + file.getAbsolutePath());  
                        String remoteFile = this.remotePath + this.seperator + filepath;  
                        System.out.println("remotePath:" + remoteFile);  
                        File rfile = new File(remoteFile);  
                        String rpath = rfile.getParent();  
                        try {  
                            createDir(rpath, sftp);  
                        } catch (Exception e) {  
                            System.out.println("*******create path failed" + rpath);  
                        }  
  
                        this.sftp.put(new FileInputStream(file), file.getName());  
                        System.out.println("=========upload down for " + localFile);  
                    }  
                }  
            }  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (SftpException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
          
    }  
    /** 
     * create Directory 
     * @param filepath 
     * @param sftp 
     */  
    private void createDir(String filepath, ChannelSftp sftp){  
        boolean bcreated = false;  
        boolean bparent = false;  
        File file = new File(filepath);  
        String ppath = file.getParent();  
        try {  
            this.sftp.cd(ppath);  
            bparent = true;  
        } catch (SftpException e1) {  
            bparent = false;  
        }  
        try {  
            if(bparent){  
                try {  
                    this.sftp.cd(filepath);  
                    bcreated = true;  
                } catch (Exception e) {  
                    bcreated = false;  
                }  
                if(!bcreated){  
                    this.sftp.mkdir(filepath);  
                    bcreated = true;  
                }  
                return;  
            }else{  
                createDir(ppath,sftp);  
                this.sftp.cd(ppath);  
                this.sftp.mkdir(filepath);  
            }  
        } catch (SftpException e) {  
            System.out.println("mkdir failed :" + filepath);  
            e.printStackTrace();  
        }  
          
        try {  
            this.sftp.cd(filepath);  
        } catch (SftpException e) {  
            e.printStackTrace();  
            System.out.println("can not cd into :" + filepath);  
        }  
          
    }  
    /** 
     * get all the files need to be upload or download 
     * @param file 
     * @return 
     */  
    private List<String> getFileEntryList(String file){  
        ArrayList<String> fileList = new ArrayList<String>();  
        InputStream in = null;  
        try {  
              
            in = new FileInputStream(file);  
            InputStreamReader inreader = new InputStreamReader(in);  
              
            LineNumberReader linreader = new LineNumberReader(inreader);  
            String filepath = linreader.readLine();  
            while(filepath != null){  
                fileList.add(filepath);  
                filepath = linreader.readLine();  
            }  
            in.close();  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }finally{  
            if(in != null){  
                in = null;  
            }  
        }  
  
        return fileList;  
    }  
  
   
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub 
    	
    	String host=args[0];
    	String username=args[1];
    	String password=args[2];
    	String localPath=args[3];
    	String remotePath=args[4];
        SFTPUtil ftp= new SFTPUtil(host,username,password,localPath,remotePath);  
        ftp.connect();  
        ftp.downloadByDirectory(remotePath, localPath); 
        ftp.disconnect();  
        System.exit(0);  
    }  
  
  
}  
